#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Time : 2021/3/30 22:18 
# @Author : wenzi
# @File : api_auth.py 
# @Software: PyCharm
from flask_httpauth import HTTPBasicAuth
from flask import jsonify
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import SignatureExpired, BadSignature

from apiRestful.settings import DevelopConfig
from apiRestful.models.user import User
from flask import request, g

auth = HTTPBasicAuth()


@auth.error_handler
def unauthorized():
    error_info = '{}'.format('Invalid credentials')
    print('api.auth.unauthorized.error_info = ' + error_info)
    response = jsonify({'error': error_info})
    response.status_code = 403

    print('api.auth.unauthorized.response = ' + str(response))

    return response


def verify_password_for_token(username, password):
    """
    验证输入的用户名和密码是否匹配
    :param username: 用户名
    :param password: 密码
    :return: 匹配结果
    """
    user = User.query.filter_by(username=username).first()
    # 注意一下，以后判断是否为空，还是写成 user is None 而不要写成 not user
    # 这样写更容易理解一些
    if user is None or not user.verify_password(password):
        # 结果不匹配
        return False

    return True


@auth.verify_password
def verify_password(username_or_token, password):
    user = verify_auth_token(username_or_token)
    if user is None:
        return verify_password_for_token(username_or_token, password)

    return user


def generator_auth_token(apiuser, expiration=600):
    s = Serializer(secret_key=DevelopConfig.SECRET_KEY, expires_in=expiration)
    token = s.dumps({'id': apiuser.id})
    return token


def verify_auth_token(token):
    s = Serializer(DevelopConfig.SECRET_KEY)

    try:
        data = s.loads(token)
    except SignatureExpired:
        return None
    except BadSignature:
        return None

    user = User.query.get(data.get('id'))

    return user


def login_required(fun):
    def inner(*args, **kwargs):
        token = request.headers.get('token')
        if not token:
            data = {
                'msg': '请登录',
                'status': 400
            }
            return jsonify(data)
        user_id = verify_auth_token(token)
        if not user_id:
            data = {
                'msg': '登录到期，请重新获取登录令牌',
                'status': 400
            }
            return jsonify(data)
        g.user_id = user_id
        return fun(*args, **kwargs)

    return inner
